﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;
using Ionic.Zip;
using Ionic.Zlib;
using System.Xml;
using Aandelendelen.Mail;
using NLog;

namespace Aandelendelen.Daily
{
	public class BackupDb : DailyJob
	{
		private static Logger logger = LogManager.GetCurrentClassLogger();

		public BackupDb(XmlNode jobNode)
			: base(jobNode, "Backing up db...")
		{}

		public override void Execute()
		{
			this.OnStart();

			try
			{
				this.BackupToZip();
			}
			catch (Exception e)
			{
				this.OnError(e);
			}

			this.OnEnd();
		}

		private void BackupToZip()
		{
			string dbPath = System.Web.Hosting.HostingEnvironment.MapPath("/App_Data/AandelenDelen.accdb");

			DateTime today = DateTime.Now;
			string todayString = today.ToString("yyyy_MM_dd_HH_mm");
			string dbBackupPath = System.Web.Hosting.HostingEnvironment.MapPath("/App_Data/AandelenDelenBackup_" + todayString + ".zip");

			try
			{
				string[] oldBackups = Directory.GetFiles(System.Web.Hosting.HostingEnvironment.MapPath("/App_Data"), "AandelenDelenBackup*.*");

				foreach (string file in oldBackups)
				{
					File.Delete(file);
				}

				//must use a stream for output, or else Zlib needs a temporary file, which doesn't work on the web...
				FileStream outputStream = new FileStream(dbBackupPath, FileMode.Create, FileAccess.Write);

				using (ZipFile zip = new ZipFile())
				{
					zip.AddFile(dbPath, "");

					zip.Save(outputStream);
				}

				outputStream.Close();

				this.MailDbBackup(dbBackupPath);
			}
			catch (Exception e)
			{
				logger.ErrorException("Backing up db failed", e);

				this.MailError(e.Message);
			}
		}

		private void MailDbBackup(string path)
		{
			if (Global.IsProductionEnvironment == false)
				return;

			try
			{
				MailArguments mailArgs = MailArguments.MailArgs;
				mailArgs.Clear();

				mailArgs["{backupsubject}"] = DateTime.Now.ToString("yyyy-MMM-dd HH:mm") + " backup";

				EMail email = MailCache.GetMail("backup");
				email.AttachmentPath = path;
				email.Recipients = "e.goldstein@quicknet.nl";

				email.QueueSingle();
			}
			catch
			{
			}
		}

		private void MailError(string errorMsg)
		{
			try
			{
				MailMessage msg = new MailMessage("backup@aandelendelen.nl", "e.goldstein@quicknet.nl", DateTime.Now.ToString("yyyy-MMM-dd HH:mm") + " BACKUP FAILED", errorMsg);

				SmtpClient smtpClient = new SmtpClient("localhost", 25);

				smtpClient.Send(msg);
			}
			catch
			{
			}
		}
	}
}